<template>
    
</template>
<script>
//import '@/page/gozhihui/gozhihui.js'
import * as THREE from 'three';
import {GLTFLoader} from 'three/examples/jsm/loaders/GLTFLoader'
import {Water} from 'three/examples/jsm/objects/Water2'
import JoyStick from '@/page/gozhihui/JoyStick';
import CannonHelper from '@/page/gozhihui/CannonHelper';
import CANNON from 'cannon';
import { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader'
//基础渲染器,照相机,场景
let renderer ,camera,scene;
let light;

initCamera();//调用照相机
initScene();//调用场景

initRenderer();//调用渲染器
//initControls();//调用控制器
initMeshes();//调用物体
render();//调要
initLight();
//定义场景
function initScene(){
    scene = new THREE.Scene();
}
//定义照相机
function initCamera(){
    camera = new THREE.PerspectiveCamera(60,window.innerWidth/window.innerHeight,.1,10000);
    camera.position.set(1,1,-1);
}
//定义物品 物品= 形状+材质
function initMeshes(){
    const hdrLoader = new RGBELoader()
    hdrLoader.loadAsync('/textures/background/005.hdr').then((texture)=>{
        texture.mapping = THREE.EquirectangularReflectionMapping;
        scene.background = texture;
        scene.environment = texture;
    })
    
    const weterGeometry = new THREE.CircleGeometry(300,64);
    const water = new Water(weterGeometry,{
        textureWidth:1024,
        textureHeight:1024,
        color:0xeeeeff,
        flowDirection:new THREE.Vector2(2,1),
        scale:1
    })
    water.rotation.x = -Math.PI/2;
    water.position.y = -4.7;
    scene.add(water)
 
 
 
};

initgrand()
function initgrand(){
    new GLTFLoader().load('/files/gltf/grand_theft_auto_san_andreas__grove_street.glb',mesh=>{
         mesh.scene.position.set(0,-10,0);
         mesh.scene.scale.set(1,1,1);
        scene.add(mesh.scene);
     })
}
//定义坐标轴
function initAxesHelper(){
     axesHelper = new THREE.AxesHelper(10);
    //scene.add(axesHelper);
}
//定义渲染器:
function initRenderer(){
     renderer = new THREE.WebGL1Renderer({ antialias: true, alpha: true });//初始化渲染器
    //renderer = new THREE.WebGL1Renderer();//初始化渲染器
    renderer.setSize(window.innerWidth,window.innerHeight);//渲染器的宽高
    document.body.appendChild(renderer.domElement);
}
function initLight(){

    light = new THREE.DirectionalLight(0xb5b1c1,1);
    light.intensity = 1.4;
    light.position.set(20,20,20);
 
    scene.add(light);
    var ambientLight = new THREE.AmbientLight(0xffffff);
    scene.add(ambientLight);
}

function render(){
    renderer.render(scene,camera)
}

window.addEventListener("resize", () => {
    //更新摄像头:
    camera.aspect = window.innerWidth / window.innerHeight;
    //更新摄影机的投影矩阵
    camera.updateProjectionMatrix();
    //更新渲染器
    renderer.setSize(window.innerWidth, window.innerHeight);
    //设置渲染器像素比
    renderer.setPixelRatio(window.devicePixelRatio);
  });
  const cannonHelper = new CannonHelper(scene);
  const world =  new CANNON.World()   ;
  world.broadphase = new CANNON.SAPBroadphase(world);
  world.gravity.set(0, -10, 0);
  world.defaultContactMaterial.friction = 0;
  const groundMaterial = new CANNON.Material("groundMaterial");
  const wheelMaterial = new CANNON.Material("wheelMaterial");
  const wheelGroundContactMaterial = new CANNON.ContactMaterial(wheelMaterial, groundMaterial, {
    friction: 0,
    restitution: 0,
    contactEquationStiffness: 1000
  });
  // 给世界添加 contactMaterial
  world.addContactMaterial(wheelGroundContactMaterial);
  
var mixers = [], clip1, clip2;
let playPosition = { x: 0, y: -.05, z: 0 };
var geometry = new THREE.BoxGeometry(.5, 1, .5);
    geometry.applyMatrix4(new THREE.Matrix4().makeTranslation(0, .5, 0));
    const target = new THREE.Mesh(geometry, new THREE.MeshNormalMaterial({
      transparent: true,
      opacity: 0
    }));
    scene.add(target);

    var directionalLight = new THREE.DirectionalLight(new THREE.Color(0xffffff), .5);
    directionalLight.position.set(0, 1, 0);
    directionalLight.castShadow = true;
    directionalLight.target = target;
    target.add(directionalLight);
const gltfLoader = new GLTFLoader();
gltfLoader.load('files/gltf/Fox.glb', mesh => {
  mesh.scene.traverse(child => {
    if (child.isMesh) {
      child.castShadow = true;
      child.material.side = THREE.DoubleSide;
    }
  });
  var player = mesh.scene;
  player.position.set( playPosition.x,  playPosition.y,  playPosition.z);
  player.scale.set(.003, .003, .003);
  target.add(player);
//    target = target;
//    player = player;
  var mixer = new THREE.AnimationMixer(player);
  clip1 = mixer.clipAction(mesh.animations[0]);
  clip2 = mixer.clipAction(mesh.animations[1]);
  clip2.timeScale = 1.6;
  mixers.push(mixer);
});
 var setup = { forward: 0, turn: 0 };
  new JoyStick({ onMove: (forward, turn) => {
    setup.forward = forward;
    setup.turn = -turn;
  }});

function updateDrive (forward = setup.forward, turn = setup.turn){
    let maxSteerVal = 0.05;
    let maxForce = .15;
    let force = maxForce * forward;
    let steer = maxSteerVal * turn;
    if (forward !== 0) {
      target.translateZ(force);
      clip2 && clip2.play();
      clip1 && clip1.stop();
    } else {
      clip2 && clip2.stop();
      clip1 && clip1.play();
    }
    target.rotateY(steer);
  }
const followCamera = new THREE.Object3D();
followCamera.position.copy(camera.position);
scene.add(followCamera);
followCamera.parent = target;

const updateCamera = () => {
  if (followCamera) {
    camera.position.lerp(followCamera.getWorldPosition(new THREE.Vector3()), 0.1);
    camera.lookAt(target.position.x, target.position.y + .5, target.position.z);
  }
}
var clock = new THREE.Clock();
var lastTime;
var fixedTimeStep = 1.0 / 60.0; 
function animate() {
    updateCamera();
    updateDrive();
    let delta = clock.getDelta();
    mixers.map(x => x.update(delta));
    let now = Date.now();
    lastTime === undefined && (lastTime = now);
    let dt = (Date.now() - lastTime) / 1000.0;
    lastTime = now;
    world.step(fixedTimeStep, dt);
    cannonHelper.updateBodies(world);
    renderer.render(scene, camera);
    requestAnimationFrame(animate);
  };
  animate();

export default{
    data(){
        return{

        }
    },
    beforeDestroy(){
    try {
		scene.clear();
		renderer.dispose();
		renderer.forceContextLoss();
		renderer.content = null;
		cancelAnimationFrame(animationID) // 去除animationFrame
		let gl = renderer.domElement.getContext("webgl");
		gl && gl.getExtension("WEBGL_lose_context").loseContext();
	}catch (e) {
		console.log(e)
	}
  }
}
</script>
<style>

</style>